﻿using Juli.Mes.Enums;
using Juli.Mes.ExcelImport.Dtos;
using Juli.Mes.Plans;
using Juli.Mes.VisionData;
using Lion.AbpPro.NotificationManagement.Notifications;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Nito.AsyncEx;
using OfficeOpenXml;
using Swashbuckle.AspNetCore.Annotations;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Domain.Repositories;

namespace Juli.Mes.ExcelImport
{
    [Route("excel")]
    public class ExcelImportAppService:MesAppService, IExcelImportAppService
    {
        private readonly IWebHostEnvironment _webHostEnv;
        private readonly IRepository<Plan> planRepository;
 
        public ExcelImportAppService(IWebHostEnvironment webHostEnv,
             IRepository<Plan> planRepository)
        {
            _webHostEnv = webHostEnv;
            this.planRepository = planRepository;
        }

        [HttpPost("template")]
        [SwaggerOperation("下载模板", Tags = ["excel"])]
        public FileResult DownloadTemplate(DownloadTemplateInputDto input)
        {
            var importType = (EnumImportType)input.Type;
            string fileName = string.Empty;
            switch (importType)
            {
                case EnumImportType.Plan:
                    fileName = "ProductionPlan.xlsx";
                    break;
                default:
                    break;
            }

            var wwwrootDir = Path.Combine(_webHostEnv.ContentRootPath, "wwwroot");
            var filePath = Path.Combine(wwwrootDir, "Template", fileName);

            string contentType;
            contentType = "application/x-xls";
            FileContentResult result = new FileContentResult(System.IO.File.ReadAllBytes(filePath), contentType)
            {
                FileDownloadName = fileName
            };

            return result;
        }

        [HttpPost("import")]
        [SwaggerOperation("导入Excel模板", Tags = ["excel"])]
        public async  Task< ImportDataOutputDto >ImportExcelFile(IFormFile uploadedFile, int type)
        {
            var returnValue = new ImportDataOutputDto();
            if (uploadedFile != null && !string.IsNullOrEmpty(uploadedFile.FileName))
            {
                using (var package = new ExcelPackage(uploadedFile.OpenReadStream()))
                {
                    try
                    {
                        var workSheets = package.Workbook.Worksheets;
                        if (workSheets.Count != 0)
                        {
                         var data     = this.GetImportData(
                             new ImportDataInputDto
                             {
                                 ExcelWorksheet = workSheets[0],
                                 Type = type
                             });

                            returnValue = await ValidateImportData(data);
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new UserFriendlyException($@"解析出错:{ex.Message}");
                    }
                }

            }

            return returnValue;
        }

        private ImportDataOutputDto GetImportData(ImportDataInputDto input)
        {
            EnumImportType inputType =(EnumImportType)input.Type;

            var returnValue=new ImportDataOutputDto();

            switch (inputType)
            {
                case EnumImportType.Plan:
                    returnValue = this.GetPlanData(input.ExcelWorksheet);
                    break;
                default:
                    break;
            }

            returnValue.Type = inputType;
            return returnValue;
        }

        private ImportDataOutputDto GetPlanData(ExcelWorksheet excelWorksheet)
        {
            var planList = new List<ImportPlanOutputDto>();
            for (var rowIterator = 2; rowIterator <= excelWorksheet.Dimension.End.Row; rowIterator++)
            {
                // 读取数据
                planList.Add(
                    new ImportPlanOutputDto
                    {
                        SmeltNo = excelWorksheet.Cells[rowIterator, 1].Value?.ToString().Trim(),
                        SteelType = excelWorksheet.Cells[rowIterator, 2].Value?.ToString().Trim(),
                        TappingTemperature = excelWorksheet.Cells[rowIterator, 3].Value?.ToString().Trim(),
                        SmeltingProcess = excelWorksheet.Cells[rowIterator, 4].Value?.ToString().Trim(),
                        SpecialProcessRequirement = excelWorksheet.Cells[rowIterator, 5].Value?.ToString().Trim(),
                    });
            }

            return new ImportDataOutputDto { PlanList = planList };
        }

        private async Task<ImportDataOutputDto> ValidateImportData(ImportDataOutputDto input)
        {
            var returnValue =new ImportDataOutputDto();
            switch (input.Type)
            {
                case EnumImportType.Plan:
                    returnValue = await this.ImportPlanData(input.PlanList);
                    break;
                default:
                    break;
            }

            return returnValue;
        }

        private async Task<ImportDataOutputDto> ImportPlanData(List<ImportPlanOutputDto> input)
        {
            foreach (var dto in input)
            {
                // 验证数据
                dto.ErrorMessage = await this.CheckPlanDto(dto);

                // 将验证通过的数据导入对应的表中
                if (string.IsNullOrWhiteSpace(dto.ErrorMessage))
                    try
                    {
                        var tappingTemperature = Convert.ToDouble(dto.TappingTemperature);

                        var plan = new Plan()
                        {
                            SmeltNo = dto.SmeltNo,
                            SteelType = dto.SteelType,
                            TappingTemperature = tappingTemperature,
                            SpecialProcessRequirement = dto.SpecialProcessRequirement,
                            SmeltingProcess = dto.SmeltingProcess,
                        };

                        await planRepository.InsertAsync(plan);

                       //todo:插入数据表
                        dto.ErrorMessage = "Success";
                    }
                    catch (Exception ex)
                    {
                        dto.ErrorMessage = ex.Message;
                    }
            }

            return new ImportDataOutputDto { PlanList = input };
        }
 
        private async Task<string> CheckPlanDto(ImportPlanOutputDto dto)
        {
            var errorMessage = string.Empty;
            if (string.IsNullOrWhiteSpace(dto.SmeltNo)) errorMessage += ";" +"熔炼号不能为空";

            await Task.Delay(500);

            return errorMessage.Trim(';');
        }
 
    }
}
